package chpt09;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * 本程序演示如何使用PorcessBuilder与Process
 *   在Java代码中启动一个单独的操作系统进程并执行相应命令
 * @author zhrb
 *
 */
public class ProcessTest {

	public static void main(String[] args) throws IOException, InterruptedException {
		/*1.准备命令字符串列表*/
		List<String> commands = new ArrayList<>();
		commands.add("cmd");// 构造所要执行的命令
		commands.add("/c"); // 必须要这个参数
		commands.add("dir");
        /*2.对ProcessBuilder进行设置*/
		ProcessBuilder pb = new ProcessBuilder(commands);
		// ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "dir");                    
		pb.directory(Path.of("d:/").toFile());// 设置工作目录到D盘
		pb.redirectErrorStream(true); // 合并输出流和错误流
		pb.redirectOutput(Path.of("d:/process.txt").toFile());//将输出定向到d:/process.txt文件
        /*3.启动Process对象(启动一个进程)*/
		Process p = pb.start();
        /*4.使用Process对象处理该进程的输入、输出*/
		// printUsingScanner(p);
		printUsingInputStreamReader(p);
		int result = p.waitFor(); // 等待进程p执行结束。p未结束时将阻塞。
		System.out.println("result:" + result); // 0代表正常结束
		int state = p.exitValue(); // 0代表正常结束
		System.out.println("执行状态：" + state);
		
		//以下为异步演示代码
		/*p.onExit().thenAccept(//异步通知
				process->System.out.println("exit value: "+ process.exitValue()));
		while(p.isAlive()) { //进程结束后跳出该循环
			System.out.println("alive"); 
			TimeUnit.MILLISECONDS.sleep(10);
		}*/
		System.out.println("main end");
	}

	private static void printUsingInputStreamReader(Process p) {
		try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream(), "GBK"));) {
			String line = null;
			while ((line = br.readLine()) != null) {
				System.out.println(line);
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	private static void printUsingScanner(Process p) {
		try (var in = new Scanner(p.getInputStream())) {
			while (in.hasNextLine()) {
				System.out.println(in.nextLine());
			}
		}
	}

}
